/*
 * poligono.c
 *
 *  Created on: 17/02/2013
 *      Author: alex
 */

#include "../headers/poligono.h"

// Función que calcula la distancia de la intersección con un cono
long double IntPoligono(long double Xe, long double Ye, long double Ze,
						long double Xd, long double Yd, long double Zd,
						long double A, long double B, long double C, long double D, struct nodo_vertice *Vertices,
						objeto_t *objeto)
{
  long double t;
  long double Ui, Vi, temp;
  long double Xi,Yi,Zi;
  struct nodo_vertice *vertice_actual, *vertice_siguiente;
  int NC, signo1, signo2;

	// Averiguar la intersección con el plano
	t = -((A * Xe + B * Ye + C * Ze + D) / (A * Xd + B * Yd + C * Zd));

	// Determinar si (Xi, Yi, Zi) están dentro del polígono
	if (t > EPSILON)
	{
		// Proyectar (Xi, Yi, Zi)
		if ((fabs(A) >= fabs(B)) && (fabs(A) >= fabs(C)))
		{
			Ui = Ye + t * Yd;
			Vi = Ze + t * Zd;
		}
		else if ((fabs(B) >= fabs(A)) && (fabs(B) >= fabs(C)))
		{
			Ui = Xe + t * Xd;
			Vi = Ze + t * Zd;
		}
		else
		{
			Ui = Xe + t * Xd;
			Vi = Ye + t * Yd;
		}

		NC = 0;
		vertice_actual = Vertices;
		while(vertice_actual != NULL)
		{
			if (vertice_actual->v - Vi < EPSILON)
				signo1 = -1;
			else
				signo1 = 1;

			vertice_siguiente = vertice_actual->siguiente;
			if (vertice_siguiente == NULL)
				vertice_siguiente = Vertices;

			if (vertice_siguiente->v -Vi < EPSILON)
				signo2 = -1;
			else
				signo2 = 1;

			if (signo1 != signo2)
			{
				if ((vertice_actual->u - Ui > EPSILON) && (vertice_siguiente->u - Ui > EPSILON))
					NC++;

				else if ((vertice_actual->u - Ui > EPSILON) || (vertice_siguiente->u - Ui > EPSILON))
				{
					temp = vertice_actual->u - Ui - vertice_actual->v - Vi * (vertice_siguiente->u - Ui - vertice_actual->u - Ui) / (vertice_siguiente->v - Vi - vertice_actual->v - Vi);
					if (temp > EPSILON)
						NC++;
				}
			}
			vertice_actual = vertice_actual->siguiente;
		}

		if ((NC % 2) != 0)
		{
			//Calcula el punto de intersección con el objeto
  			Xi = (Xe + t * Xd);
  			Yi = (Ye + t * Yd);
  			Zi = (Ze + t * Zd);

  			if (Cortar(objeto,Xi,Yi,Zi) == 1)
				return t;
			else
				return -1.0;
		}
		else
			return -1.0;
	}
	return -1.0;
}

long double* NormalPoligono(long double N[3])
{
  long double *Normal;

    Normal = (long double*)malloc(3 * sizeof(long double));
  	Normal[0] = N[0];
  	Normal[1] = N[1];
  	Normal[2] = N[2];

  	return Normal;
}
